import { PropType, defineComponent, h } from 'vue';
import { useNamespace } from '@ibiz-template/vue3-util';
import { IModal } from '@ibiz-template/runtime';
import { ImagePreview } from './components';
import { getFileType, useFilesParse } from './file-util';
import { GridRowState, GridFieldColumnController } from '../../controller';
import './attachment-viewer-column.scss';

export const AttachmentViewerColumn = defineComponent({
  name: 'IBizAttachmentViewerColumn',
  props: {
    controller: {
      type: Object as PropType<GridFieldColumnController>,
      required: true,
    },
    row: {
      type: Object as PropType<GridRowState>,
      required: true,
    },
  },
  setup(props) {
    const ns = useNamespace('grid-field-column');
    const ns2 = useNamespace('attachment-viewer-column');
    const c = props.controller;
    const { downloadUrl, files, onDownload } = useFilesParse(props, c);

    /** 处理图片预览 */
    const handleImagePreview = async (file: IData): Promise<void> => {
      const overlay = ibiz.overlay.createModal(
        (modal: IModal) => {
          return h(ImagePreview, {
            file,
            modal,
          });
        },
        undefined,
        {
          modalClass: ns.e('image-preview'),
          width: 700,
          height: 'auto',
        },
      );
      overlay.present();
      await overlay.onWillDismiss();
    };

    /** 处理PDF预览 */
    const handlePDFPreview = async (file: IData): Promise<void> => {
      const url = file.url || downloadUrl.value.replace('%fileId%', file.id);
      // 适配 url 拉起的文件没有 Content-Type 的情况。没有 Content-Type , link.click()会直接调用下载逻辑
      const response = await ibiz.net.request(url, {
        method: 'get',
        responseType: 'blob',
        baseURL: '', // 已经有baseURL了，这里无需再写
      });
      if (response.data) {
        const blob = new Blob([response.data as Blob], {
          type: 'application/pdf',
        });
        // 创建对象 URL
        const objectURL = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = objectURL;
        link.target = '_blank';
        link.style.cursor = 'pointer';
        link.textContent = file.name || '';
        const handleClick = function (): void {
          link.removeEventListener('click', handleClick);
          document.body.removeChild(link);
        };
        link.addEventListener('click', handleClick);
        document.body.appendChild(link);
        link.click();
      }
    };

    const handleFileClick = (file: IData): void => {
      const fileName = file.name;
      const fileExtension = fileName.split('.').pop()?.toLowerCase() ?? '';
      switch (getFileType(fileExtension)) {
        case 'image':
          // 打开图片预览
          handleImagePreview(file);
          break;
        case 'pdf':
          // 打开pdf预览
          handlePDFPreview(file);
          break;
        case 'other':
        default:
          // 直接下载文件
          onDownload(file);
          break;
      }
    };

    const renderImage = (file: IData): JSX.Element => {
      const imageUrl = file.base64 || file.url || '';
      return <img class={ns2.be('file-item', 'img')} src={imageUrl} alt='' />;
    };

    const renderOtherFile = (file: IData): JSX.Element => {
      return (
        <div class={ns2.be('file-item', 'caption')} title={file.name}>
          {file.name}
        </div>
      );
    };

    const renderFileItem = (file: IData): JSX.Element | void => {
      const fileName = file.name;
      const fileExtension = fileName.split('.').pop()?.toLowerCase() ?? '';

      switch (getFileType(fileExtension)) {
        case 'image':
          return renderImage(file);
        case 'pdf':
        case 'other':
        default:
          return renderOtherFile(file);
      }
    };

    const renderFiles = (): JSX.Element => {
      return (
        <div class={ns2.b('content')}>
          {files.value?.map((file: IData) => {
            return (
              <div
                class={ns2.b('file-item')}
                onClick={() => handleFileClick(file)}
              >
                {renderFileItem(file)}
              </div>
            );
          })}
        </div>
      );
    };

    return {
      ns,
      ns2,
      renderFiles,
    };
  },
  render() {
    const c = this.controller;

    return (
      <div
        class={[
          this.ns.b(),
          this.ns2.b(),
          c.clickable(this.row) && this.ns.m('clickable'),
          this.ns.m(this.controller.grid.overflowMode),
          this.controller.model.cellSysCss?.cssName,
          this.ns.is('has-action', !!c.model.deuiactionGroup),
        ]}
      >
        {this.renderFiles()}
      </div>
    );
  },
});
export default AttachmentViewerColumn;
